package one.mixin.pasteboard


import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.util.Log
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import androidx.core.content.FileProvider
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.util.UUID
import java.util.concurrent.Executors

/** PasteboardPlugin */
class PasteboardPlugin : FlutterPlugin, MethodCallHandler {
    private val TAG = "PasteboardPlugin"   
    /// The MethodChannel that will the communication between Flutter and native Android
    ///
    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
    /// when the Flutter Engine is detached from the Activity
    private lateinit var context: Context
    private lateinit var channel: MethodChannel

    private val executor = Executors.newSingleThreadExecutor()

    override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        channel = MethodChannel(flutterPluginBinding.binaryMessenger, "pasteboard")
        channel.setMethodCallHandler(this)
        context = flutterPluginBinding.applicationContext
    }

    override fun onMethodCall(call: MethodCall, result: Result) {
    Log.d(TAG, "2222222222 PasteboardPlugin.kt onMethodCall: ${call.method} 01")
    val manager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        val cr = context.contentResolver
        val first = manager.primaryClip?.getItemAt(0)
        Log.d(TAG, "2222222222 PasteboardPlugin.kt onMethodCall: ${manager.primaryClip?.getItemAt(0)} 02")
        when (call.method) {
            "image" -> {
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call image: ${call.method} 01")
                 executor.run {
                     Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call image: ${first?.uri}  07")
                     val uri = first?.uri ?: return@run result.success(null)
//                    val uri = if (first == null) {
//                    Log.d(TAG, "2222222222 PasteboardPlugin.kt first is null, returning success(null)")
//                    return@run result.success(null)
//                    } else if (first.uri == null) {
//                        Log.d(TAG, "2222222222 PasteboardPlugin.kt first.uri is null, returning success(null)")
//                        return@run result.success(null)
//                    } else {
//                        Log.d(TAG, "2222222222 PasteboardPlugin.kt Successfully retrieved uri: ${first.uri}")
//                        first.uri
//                    }
                    Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call image: ${call.method} 04")
                    val mime = cr.getType(uri)
                    if (mime == null || !mime.startsWith("image")) return@run result.success(null)
                    Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call image: ${call.method} 05")
                    val bytes =
                        cr.openInputStream(uri)?.readBytes() ?: return@run result.success(null)
                    Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call image: ${call.method} 06")
                    result.success(bytes)
                    Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call image: ${call.method} 03_1")
                 }
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call image: ${call.method} 02")
            }

            "files" -> {
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call files: ${call.method} 01")
                manager.primaryClip?.run {
                    if (itemCount == 0) result.success(null)
                    val files: MutableList<String> = mutableListOf()
                    for (i in 0 until itemCount) {
                        getItemAt(i).uri?.let {
                            files.add(it.toString())
                        }
                        Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call files: ${call.method} 03")
                    }
                    result.success(files)
                }
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call files: ${call.method} 02")
            }

            "html" -> {
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call html: ${call.method} 01")
                result.success(first?.htmlText)
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call html: ${call.method} 02")
            }
            "writeFiles" -> {
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeFiles: 01")
                val args = call.arguments<List<String>>() ?: return result.error(
                    "NoArgs",
                    "Missing Arguments",
                    null,
                )
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeFiles: ${args} 02")
                var clip: ClipData? = null
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeFiles: $clip 07")
                for (i in args) {
                    val uri = Uri.parse(i)
                    Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeFiles: $uri 08")
                    clip = clip ?: ClipData.newUri(cr, "files", uri)
                    Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeFiles: $clip 09")
                    clip?.addItem(ClipData.Item(uri))
                    Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeFiles: 03")
                }

                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeFiles: 04")
                clip?.let {
                    manager.setPrimaryClip(it)
                    Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeFiles: 06")
                }
                result.success(null)
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeFiles: 05")
            }

            "writeImage" -> {
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeImage: 01")
                val image = call.arguments<ByteArray>() ?: return result.error(
                    "NoArgs",
                    "Missing Arguments",
                    null,
                )
                Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeImage: $image 02")
                // val name = UUID.randomUUID().toString() + ".png"
                val name = "test.png"
                val file = File(context.cacheDir, name)

                executor.execute {
                    try {
                        Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeImage: 03")
                        val bitmap = BitmapFactory.decodeByteArray(image, 0, image.size)
                        val out = ByteArrayOutputStream()
                        bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)

                        FileOutputStream(file).use {
                            out.writeTo(it)
                            Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeImage: 04")
                        }

                        val uri = FileProvider.getUriForFile(
                            context, "${context.packageName}.provider", file
                        )
                        val clip = ClipData.newUri(cr, "image.png", uri)
                        manager.setPrimaryClip(clip)
                        result.success(null)
                        Log.d(TAG, "2222222222 PasteboardPlugin.kt Received method call writeImage: 05")
                    } catch (e: Exception) {
                        Log.e(TAG, "2222222222 PasteboardPlugin.kt Received method call writeImage: 06")
                        result.error("Error", "Failed to write image", e.message)
                    }
                }
            }

            else -> result.notImplemented()
        }
        Log.d(TAG, "2222222222 PasteboardPlugin.kt onMethodCall: ${call.method} 03")
    }

    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
        Log.d(TAG, "2222222222 PasteboardPlugin.kt onDetachedFromEngine")   
    }
}